package config

import (
	"errors"
	"fmt"
	"github.com/BurntSushi/toml"
	"go.uber.org/zap"
	"os"
	"path/filepath"
	"regexp"
	"runtime"
	"starry_sky/internal/core"
)

type AllLogConfig struct {
	WebLogConfig    *WebLogConfig    `toml:"webLogConfig" json:"webLogConfig"`
	SystemLogConfig *SystemLogConfig `json:"systemLogConfig" toml:"systemLogConfig"`
	AccessLogConfig *AccessLogConfig `json:"accessLogConfig" toml:"accessLogConfig"`
}

type WebLogConfig struct {
	//log调用名称
	LoggerName string `toml:"loggerName"`
	//log文件前缀
	FilePrefix string `toml:"filePrefix"`
	//log存储路径3
	Path string `toml:"path"`
	//log保存等级
	LogLevel int8 `toml:"logLevel"`
	//输出方式
	OutputMode string `toml:"outputMode"`
	//是否显示日志输出的文件和行号
	ShowCaller bool `toml:"showCaller"`
	//zapLogger
	Logger *zap.Logger
}

type SystemLogConfig struct {
	//log调用名称
	LoggerName string `toml:"loggerName"`
	//log文件前缀
	FilePrefix string `toml:"filePrefix"`
	//log存储路径3
	Path string `toml:"path"`
	//log保存等级
	LogLevel int8 `toml:"logLevel"`
	//输出方式
	OutputMode string `toml:"outputMode"`
	//是否显示日志输出的文件和行号
	ShowCaller bool `toml:"showCaller"`
	//zapLogger
	Logger *zap.Logger
}

type AccessLogConfig struct {
	Blacklist []string `toml:"blacklist"`
	Whitelist []string `toml:"whitelist"`
	BlackSet  core.Set
	WhiteSet  core.Set
}

var LogConfig *AllLogConfig

func InitLogConfig() {
	//读取配置文件部分
	filePath, err := filepath.Abs("./config/log_config.toml")
	if err != nil {
		panic(err)
	}
	if _, err := toml.DecodeFile(filePath, &LogConfig); err != nil {
		fmt.Println(err.Error())
		panic(errors.New("logger配置文件读取失败"))
	}
	// 写入默认值
	LogConfig.SystemLogConfig.Path = getLogPath(LogConfig.SystemLogConfig.Path, LogConfig.SystemLogConfig.LoggerName)
	LogConfig.WebLogConfig.Path = getLogPath(LogConfig.WebLogConfig.Path, LogConfig.WebLogConfig.LoggerName)
	if len(LogConfig.AccessLogConfig.Whitelist) > 0 {
		LogConfig.AccessLogConfig.WhiteSet = core.NewSet()
		for _, s := range LogConfig.AccessLogConfig.Whitelist {
			LogConfig.AccessLogConfig.WhiteSet.Add(s)
		}
	}
	if len(LogConfig.AccessLogConfig.Blacklist) > 0 {
		LogConfig.AccessLogConfig.BlackSet = core.NewSet()
		for _, s := range LogConfig.AccessLogConfig.Blacklist {
			LogConfig.AccessLogConfig.BlackSet.Add(s)
		}
	}
}

func getLogPath(path string, loggerName string) string {
	if isAbsolutePath(path) {
		return path
	}
	if path == "" {
		//组装为当前项目路径下logs文件夹下的LoggerName文件夹的绝对路径
		return filepath.Join(filepath.Dir(os.Args[0]), "/logs", loggerName)
	} else {
		return filepath.Join(filepath.Dir(os.Args[0]), path)
	}
}
func isAbsolutePath(path string) bool {
	switch runtime.GOOS {
	case "windows":
		// Windows 系统：匹配以驱动器号和斜杠或反斜杠开头的路径
		matched, _ := regexp.MatchString(`^[a-zA-Z]:[\\/].*`, path)
		return matched
	default:
		// 其他系统（包括 Unix-like 系统）
		return filepath.IsAbs(path)
	}
}

//返回路径
